home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / libg_261.zip / libg_261 / libg++ / src / SLList.cc < prev    next >
C/C++ Source or Header  |  1994-08-31  |  5KB  |  248 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /* 
  3. Copyright (C) 1988, 1992 Free Software Foundation
  4.     written by Doug Lea (dl@rocky.oswego.edu)
  5.  
  6. This file is part of the GNU C++ Library.  This library is free
  7. software; you can redistribute it and/or modify it under the terms of
  8. the GNU Library General Public License as published by the Free
  9. Software Foundation; either version 2 of the License, or (at your
  10. option) any later version.  This library is distributed in the hope
  11. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  12. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  13. PURPOSE.  See the GNU Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free Software
  16. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18.  
  19. #ifndef _G_NO_TEMPLATES
  20. #ifdef __GNUG__
  21. //#pragma implementation
  22. #endif
  23. #include <limits.h>
  24. #include <stream.h>
  25. #include <builtin.h>
  26. #include "SLList.h"
  27.  
  28. void BaseSLList::error(const char* msg) const
  29. {
  30.   (*lib_error_handler)("SLList", msg);
  31. }
  32.  
  33. int BaseSLList::length() const
  34. {
  35.   int l = 0;
  36.   BaseSLNode* t = last;
  37.   if (t != 0) do { ++l; t = t->tl; } while (t != last);
  38.   return l;
  39. }
  40.  
  41. void BaseSLList::clear()
  42. {
  43.   if (last == 0)
  44.     return;
  45.  
  46.   BaseSLNode* p = last->tl;
  47.   last->tl = 0;
  48.   last = 0;
  49.  
  50.   while (p != 0)
  51.   {
  52.     BaseSLNode* nxt = p->tl;
  53.     delete_node(p);
  54.     p = nxt;
  55.   }
  56. }
  57.  
  58.  
  59. // Note:  This is an internal method.  It does *not* free old contents!
  60.  
  61. void BaseSLList::copy(const BaseSLList& a)
  62. {
  63.   if (a.last == 0)
  64.     last = 0;
  65.   else
  66.   {
  67.     BaseSLNode* p = a.last->tl;
  68.     BaseSLNode* h = copy_node(p->item());
  69.     last = h;
  70.     for (;;)
  71.     {
  72.       if (p == a.last)
  73.       {
  74.         last->tl = h;
  75.         return;
  76.       }
  77.       p = p->tl;
  78.       BaseSLNode* n = copy_node(p->item());
  79.       last->tl = n;
  80.       last = n;
  81.     }
  82.   }
  83. }
  84.  
  85. BaseSLList& BaseSLList::operator = (const BaseSLList& a)
  86. {
  87.   if (last != a.last)
  88.   {
  89.     clear();
  90.     copy(a);
  91.   }
  92.   return *this;
  93. }
  94.  
  95. Pix BaseSLList::prepend(const void *datum)
  96. {
  97.   return prepend(copy_node(datum));
  98. }
  99.  
  100.  
  101. Pix BaseSLList::prepend(BaseSLNode* t)
  102. {
  103.   if (t == 0) return 0;
  104.   if (last == 0)
  105.     t->tl = last = t;
  106.   else
  107.   {
  108.     t->tl = last->tl;
  109.     last->tl = t;
  110.   }
  111.   return Pix(t);
  112. }
  113.  
  114.  
  115. Pix BaseSLList::append(const void *datum)
  116. {
  117.   return append(copy_node(datum));
  118. }
  119.  
  120. Pix BaseSLList::append(BaseSLNode* t)
  121. {
  122.   if (t == 0) return 0;
  123.   if (last == 0)
  124.     t->tl = last = t;
  125.   else
  126.   {
  127.     t->tl = last->tl;
  128.     last->tl = t;
  129.     last = t;
  130.   }
  131.   return Pix(t);
  132. }
  133.  
  134. void BaseSLList::join(BaseSLList& b)
  135. {
  136.   BaseSLNode* t = b.last;
  137.   b.last = 0;
  138.   if (last == 0)
  139.     last = t;
  140.   else if (t != 0)
  141.   {
  142.     BaseSLNode* f = last->tl;
  143.     last->tl = t->tl;
  144.     t->tl = f;
  145.     last = t;
  146.   }
  147. }
  148.  
  149. Pix BaseSLList::ins_after(Pix p, const void *datum)
  150. {
  151.   BaseSLNode* u = (BaseSLNode*)p;
  152.   BaseSLNode* t = copy_node(datum);
  153.   if (last == 0)
  154.     t->tl = last = t;
  155.   else if (u == 0) // ins_after 0 means prepend
  156.   {
  157.     t->tl = last->tl;
  158.     last->tl = t;
  159.   }
  160.   else
  161.   {
  162.     t->tl = u->tl;
  163.     u->tl = t;
  164.     if (u == last) 
  165.       last = t;
  166.   }
  167.   return Pix(t);
  168. }
  169.  
  170. void BaseSLList::del_after(Pix p)
  171. {
  172.   BaseSLNode* u = (BaseSLNode*)p;
  173.   if (last == 0 || u == last) error("cannot del_after last");
  174.   if (u == 0) u = last; // del_after 0 means delete first
  175.   BaseSLNode* t = u->tl;
  176.   if (u == t)
  177.     last = 0;
  178.   else
  179.   {
  180.     u->tl = t->tl;
  181.     if (last == t)
  182.       last = u;
  183.   }
  184.   delete_node(t);
  185. }
  186.  
  187. int BaseSLList::owns(Pix p) const
  188. {
  189.   BaseSLNode* t = last;
  190.   if (t != 0 && p != 0)
  191.   {
  192.     do
  193.     {
  194.       if (Pix(t) == p) return 1;
  195.       t = t->tl;
  196.     } while (t != last);
  197.   }
  198.   return 0;
  199. }
  200.  
  201. int BaseSLList::remove_front(void *dst, int signal_error)
  202. {
  203.   if (last)
  204.   {
  205.     BaseSLNode* t = last->tl;
  206.     copy_item(dst, t->item());
  207.     if (t == last)
  208.       last = 0;
  209.     else
  210.       last->tl = t->tl;
  211.     delete_node(t);
  212.     return 1;
  213.   }
  214.   if (signal_error)
  215.     error("remove_front of empty list");
  216.   return 0;
  217. }
  218.  
  219. void BaseSLList::del_front()
  220. {
  221.   if (last == 0) error("del_front of empty list");
  222.   BaseSLNode* t = last->tl;
  223.   if (t == last)
  224.     last = 0;
  225.   else
  226.     last->tl = t->tl;
  227.   delete_node(t);
  228. }
  229.  
  230. int BaseSLList::OK() const
  231. {
  232.   int v = 1;
  233.   if (last != 0)
  234.   {
  235.     BaseSLNode* t = last;
  236.     long count = LONG_MAX;      // Lots of chances to find last!
  237.     do
  238.     {
  239.       count--;
  240.       t = t->tl;
  241.     } while (count > 0 && t != last);
  242.     v &= count > 0;
  243.   }
  244.   if (!v) error("invariant failure");
  245.   return v;
  246. }
  247. #endif /*!_G_NO_TEMPLATES*/
  248.